package model

import (
	"fmt"
	"time"
)

var (
	NUM = 8
)

func GoroutineTest() {
	numChan := make(chan int, 2000)
	numChanExit := make(chan bool, NUM)
	resChan := make(chan map[int]int, 2000)

	go writeNum(numChan, numChanExit)
	for i := 0; i < 8; i++ {
		go readNum(numChan, numChanExit, resChan)
	}

	for {
		fmt.Println("等待执行完成")
		flag := 0
		for i := 0; i < NUM; i++ {
			<-numChanExit
			flag++
		}
		if flag == NUM {
			//关闭标记通道
			close(numChanExit)
			//关闭res管道
			close(resChan)
			fmt.Println("读写完成，关闭标记、结果通道，开始遍历结果通道中的数据")
			for v := range resChan {
				fmt.Println(v)
			}
			//结束循环
			break
		}
	}
}

//写数字管道
func writeNum(numChan chan int, numChanExit chan bool) {
	for i := 1; i <= 20; i++ {
		time.Sleep(time.Second / 10)
		fmt.Println("写数据。。", i)
		numChan <- i
	}
	fmt.Println("写操作已经完成，关闭数据写管道")
	//关闭写通道
	close(numChan)
}

//写数字管道
func readNum(numChan chan int, numChanExit chan bool, resChan chan map[int]int) {
	for {
		v, ok := <-numChan
		if !ok {
			break
		}
		fmt.Println("读数据。。", v)
		res := nums(v)
		resChan <- map[int]int{
			v: res,
		}
	}
	fmt.Println("协程取不到数据了，写入标记，来表示执行完成")
	numChanExit <- true
}

func nums(n int) int {
	res := 0
	for i := 0; i < n; i++ {
		res += i
	}
	return res
}
